package nonDictionaryTokenAnalyzer;

import java.util.ArrayList;
import java.util.Hashtable;

import main.tokens;
import inporter.TokenInporter;

public class SpitTokenProcessor 
{
	//Hash table which contains all dictionary words
	private Hashtable<String, String> htDicTokens;
	//Hash table which contains all tokens(divided by the length of alphabets)
	private Hashtable<String, ArrayList<tokens>> htAlphaTokens;
	
	//get tokens from files
	TokenInporter clsTInporter = new TokenInporter();
	Hashtable<String, String> htFileTokens;
	
	//Array list for storing the results
	ArrayList<String> arlPossibleResults;
	
	
	public SpitTokenProcessor(Hashtable<String, String> pDicTokens, Hashtable<String, ArrayList<tokens>> pAlphaTokens)
	{
		htDicTokens = pDicTokens;
		htAlphaTokens = pAlphaTokens;
		
		//get tokens from files
		clsTInporter.arlGetFileLines("input\\source.txt");
		htFileTokens = clsTInporter.getFileToken();
		
	}
	
	/*
	 * Function: Main function of splitting process, call [strSplit] function recursively to get to result
	 * Input: pToken -> Current token which needs to be split
	 * Output: strRtn -> The result of processor
	 */
	public String getProcessorResult(String pAlphaToken)
	{
		//System.out.println("in: " + pAlphaToken);
		String strRtn = "";

		arlPossibleResults = strSplit(pAlphaToken, 1);
		
		if (arlPossibleResults != null)
		{
			for (int i = 0; i < arlPossibleResults.size(); i ++)
			{
				//System.out.println(arlPossibleResults.get(i));
				if (!strRtn.contains(arlPossibleResults.get(i)) && bolFileTokenCheck(arlPossibleResults.get(i)))
				{
					strRtn = strRtn + arlPossibleResults.get(i) + ", ";
				}				
			}
			if (strRtn.contains(", "))
			{
				strRtn = strRtn.substring(0, strRtn.length() - 2);
			}
		}
		//System.out.println("out");
		return strRtn;
	}
	
	/*
	 * Function: this is the recursive function for splitting token
	 * Input: pCntToken -> Current token (part of token) which needs to be split
	 * 		  pSplitLoc -> Split location for current token
	 * Output: strRtn -> Result
	 */
	private ArrayList<String> strSplit(String pCntToken, int pCntSplitLoc)
	{
		ArrayList<String> arlRtn = new ArrayList<String>();
		
		// set the starting split location for next level
		int intNextSplitLoc = 1;
		if (pCntSplitLoc == 1)
		{
			intNextSplitLoc = 2;
		}
		
		// Check the reference for whole token first
		ArrayList<String> arlTmpCntToken = arlReferenceScanner(pCntToken);
		if (arlTmpCntToken != null)
		{
			// result found for current token, save to the result array list
			for (int i = 0; i < arlTmpCntToken.size(); i ++)
			{
				arlRtn.add(arlTmpCntToken.get(i));
			}
		}
		
		// start the loop until no split point
		while(pCntSplitLoc < pCntToken.length())
		{
			// get the left part and right part
			String strTokenLeft = pCntToken.substring(0, pCntSplitLoc);
			String strTokenRight = pCntToken.substring(pCntSplitLoc);
			
			//***************************************************************
			//System.out.println("Current left: "+ strTokenLeft + ", Current Right: " + strTokenRight);
			//***************************************************************
			
			// temporary result for left part, right part 
			ArrayList<String> arlTmpLeft = null;
			
			// get the result for the current left part
			if (strTokenLeft.length() == 1)
			{
				arlTmpLeft = new ArrayList<String>();
				arlTmpLeft.add(strTokenLeft);
			}
			else
			{
				arlTmpLeft = arlReferenceScanner(strTokenLeft);
			}
			
			// Check left part's result
			if (arlTmpLeft != null)
			{
				// result found for left part, now deal with right part
				
				//***************************************
				// Abbreviation process should be here 
				//***************************************
				
				// take right part as a new non-dictionary token, sand pass it to strSplit function
				ArrayList<String> arlTmpResult = strSplit(strTokenRight, intNextSplitLoc);
				
				
				if (arlTmpResult != null)
				{
					// save result to current level's array list
					for(int i = 0; i < arlTmpLeft.size(); i ++)
					{
						for (int j = 0; j < arlTmpResult.size(); j ++)
						{
							arlRtn.add(arlTmpLeft.get(i) + " " + arlTmpResult.get(j));
						}
					}
				}				
				
			}
			
			// pCntSplitLoc increase
			pCntSplitLoc ++;
		}
		
		if (arlRtn.size() == 0)
		{
			return null; 
		}
		else
		{
			return arlRtn;
		}
		
	}
	
	/*
	 * Function: Scan the references to check current token is dictionary word or not
	 * Input: pCntToken -> Current Token
	 * Output: strRtn -> Result
	 */
	private ArrayList<String> arlReferenceScanner(String pCntToken)
	{
		//********************************************************
		//System.out.println("Reference check for: " + pCntToken);
		//**********************************************************
		ArrayList<String> arlRefRtn = new ArrayList<String>();
		
		//Check abbreviation result first
		if (htAlphaTokens.get(pCntToken) != null)
		{
			String strRtn = htAlphaTokens.get(pCntToken).get(0).getResult();
			if (!strRtn.equals(""))
			{
				if (strRtn.contains(", "))
				{
					String[] strsTmp = strRtn.split(", ");					
					for (int i = 0; i < strsTmp.length; i ++)
					{
						arlRefRtn.add(strsTmp[i].trim());
					}
				}
			}
		}
		
		//Check tokens in files
		if (htFileTokens.get(pCntToken) != null)
		{
			arlRefRtn.add(htFileTokens.get(pCntToken));
		}
		//Check dictionary at last
		if (htDicTokens.get(pCntToken) != null)
		{
			arlRefRtn.add(htDicTokens.get(pCntToken));
		}
		
		//********************************************************
		//System.out.println("Reference check result: " + strRtn);
		//**********************************************************
		if (arlRefRtn.size() != 0)
		{
			return arlRefRtn;
		}
		else
		{
			return null;
		}
		
	}
	
	/*
	 * Function: Check result contains File token or not
	 * Input: pCntResult -> current result which needs to be checked
	 * Output: bolRtn -> true: contains, false: not
	 */
	private boolean bolFileTokenCheck(String spCntResult)
	{
		boolean bolRtn = false;
		
		String[] strsCntResult = spCntResult.split(" ");
		for (int i = 0; i < strsCntResult.length; i ++)
		{
			if (htFileTokens.get(strsCntResult[i]) != null)
			{
				bolRtn = true;
			}
		}
		
		return bolRtn;
	}
}
